package com.mark.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import com.mark.entity.message.text.TextReqMsg;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.apache.commons.lang3.CharEncoding;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * XmlUtil.java
 *
 * @author malq
 * @description: xml转换工具<p/>
 * Details:
 * <项目描述></p>
 * @since 最终编辑于2016年下午8:39:34
 */
public class XmlUtil {
    public static String req2xml(HttpServletRequest request) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                request.getInputStream()));
        String str = null;
        StringBuffer buffer = new StringBuffer();
        while ((str = reader.readLine()) != null) {
            buffer.append(str);
        }
        return buffer.toString();

    }

    /**
     * 对象转xml
     *
     * @param obj
     * @return
     */
    public static String toXml(Object obj) {
        XStream xstream = new XStream(new DomDriver("utf8"));
        xstream.processAnnotations(obj.getClass()); // 识别obj类中的注解
        /*
		 * // 以压缩的方式输出XML StringWriter sw = new StringWriter();
		 * xstream.marshal(obj, new CompactWriter(sw)); return sw.toString();
		 */
        // 以格式化的方式输出XML
        return xstream.toXML(obj);
    }

    /**
     * xml转对象
     *
     * @param xmlStr
     * @param cls
     * @return
     */
    public static <T> T toBean(String xmlStr, Class<T> cls) {
        XStream xstream = new XStream(new DomDriver());
        xstream.processAnnotations(cls);
        Object obj = xstream.fromXML(xmlStr);
        try {
            return cls.cast(obj);
        } catch (ClassCastException e) {
            return null;
        }
    }

    /**
     * 获取消息类型。因为使用了继承的方式，基础类型节点不包含所有消息类型，导致转换出错。故使用dom4j解析，防止报错。
     * 在微信消息格式固定的情况下，完全可以满足。
     *
     * @param xmlStr
     * @return
     */
    public static String getMsgType(String xmlStr,String tagName) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        String result = MessageUtil.REQ_MESSAGE_TYPE_TEXT;
        try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(xmlStr.getBytes(CharEncoding.UTF_8)));
            if (doc.getElementsByTagName(tagName).item(0).getFirstChild() != null) {
                result = doc.getElementsByTagName(tagName).item(0).getFirstChild().getNodeValue();
            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


    public static void main(String[] args) {
//		String xml = "<xml><ToUserName><![CDATA[gh_91aec5aca744]]></ToUserName>\n" +
//				"<FromUserName><![CDATA[oGJLnwMMurjrZwRdpjYyv8y2oGHw]]></FromUserName>\n" +
//				"<CreateTime>1501409468</CreateTime>\n" +
//				"<MsgType><![CDATA[text]]></MsgType>\n" +
//				"<Content><![CDATA[老马]]></Content>\n" +
//				"<MsgId>6448504563420890329</MsgId>\n" +
//				"</xml>";
//		String result = getMsgType(xml);
//		System.out.println(result);


        String req = "<xml><ToUserName><![CDATA[gh_91aec5aca744]]></ToUserName>\n" +
                "<FromUserName><![CDATA[oGJLnwMMurjrZwRdpjYyv8y2oGHw]]></FromUserName>\n" +
                "<CreateTime>1501413271</CreateTime>\n" +
                "<MsgType><![CDATA[text]]></MsgType>\n" +
                "<Content><![CDATA[老马]]></Content>\n" +
                "<MsgId>6448520897181517909</MsgId>\n" +
                "</xml>";
        TextReqMsg reqMsg = toBean(req, TextReqMsg.class);
        System.out.println(reqMsg.getContent());
    }

}
